package com.basker.pisces.excel.poi.utils;

import java.util.Calendar;
import java.util.Date;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.DataFormat;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import com.basker.pisces.excel.CellModel;
import com.basker.pisces.excel.CellStyleModel;
import com.basker.pisces.excel.enums.CellValueType;

public class POIExcelUtils {
    public static CellStyle createCellStyle(Workbook workbook, CellStyleModel styleModel) {
        CellStyle cellStyle = workbook.createCellStyle();

        if (styleModel.isFontBold()) {
            Font font = workbook.createFont();
            font.setBold(true);

            cellStyle.setFont(font);
        }

        String format = styleModel.getFormat();
        if (!StringUtils.isEmpty(format)) {
            DataFormat createDataFormat = workbook.createDataFormat();
            short formatVal = createDataFormat.getFormat(format);

            cellStyle.setDataFormat(formatVal);
        }

        return cellStyle;

    }

    public static Object getCellValue(Cell poiCell) {
        Assert.notNull(poiCell, "parameter 'poiCell' is required");

        CellType cellType = poiCell.getCellType();

        if (cellType.equals(CellType.STRING)) {
            return poiCell.getStringCellValue();
        }

        if (cellType.equals(CellType.BLANK)) {
            return null;
        }

        if (cellType.equals(CellType.NUMERIC)) {
            return poiCell.getNumericCellValue();
        }

        if (cellType.equals(CellType.BOOLEAN)) {
            return poiCell.getBooleanCellValue();
        }

        // other 2 types
        // CellType.FORMULA
        // CellType.ERROR

        return poiCell.getStringCellValue();
    }

    public static CellType getPOICellType(CellModel cell) {
        Assert.notNull(cell, "parameter 'cell' is required");

        CellValueType valueType = cell.getValueType();

        if (valueType == CellValueType.String) {
            return CellType.STRING;
        }

        if (valueType == CellValueType.Number) {
            return CellType.NUMERIC;
        }

        if (valueType == CellValueType.Date) {
            return CellType.NUMERIC;
        }

        if (valueType == CellValueType.Boolean) {
            return CellType.BOOLEAN;
        }

        if (valueType == CellValueType.Blank) {
            return CellType.BLANK;
        }

        return CellType.BLANK;
    }

    public static void setCellValue(Cell poiCell, Object value) {
        Assert.notNull(poiCell, "parameter 'poiCell' is required");

        CellType cellType = poiCell.getCellType();
        if (cellType.equals(CellType.BLANK) || value == null) {
            return;
        }

        if (value instanceof Date) {
            poiCell.setCellValue((Date) value);
        } else if (value instanceof Calendar) {
            poiCell.setCellValue((Calendar) value);
        } else if (value instanceof Number) {
            poiCell.setCellValue(((Number) value).doubleValue());
        } else if (value instanceof Boolean) {
            poiCell.setCellValue((Boolean) value);
        } else {
            poiCell.setCellValue(value.toString());
        }

    }

}
